/**
 */
package fUML.Semantics.Activities.IntermediateActivities;

import fUML.Semantics.Classes.Kernel.Value;

import fUML.Semantics.CommonBehaviors.BasicBehaviors.Execution;

import fUML.Syntax.Classes.Kernel.ValueSpecification;

import org.eclipse.emf.common.util.EList;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Decision Node Activation</b></em>'.
 * <!-- end-user-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link fUML.Semantics.Activities.IntermediateActivities.DecisionNodeActivation#getDecisionInputExecution <em>Decision Input Execution</em>}</li>
 * </ul>
 * </p>
 *
 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getDecisionNodeActivation()
 * @model
 * @generated
 */
public interface DecisionNodeActivation extends ControlNodeActivation {
	/**
	 * Returns the value of the '<em><b>Decision Input Execution</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The current execution of the decision input behavior (if any).
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Decision Input Execution</em>' containment reference.
	 * @see #setDecisionInputExecution(Execution)
	 * @see fUML.Semantics.Activities.IntermediateActivities.IntermediateActivitiesPackage#getDecisionNodeActivation_DecisionInputExecution()
	 * @model containment="true" ordered="false"
	 * @generated
	 */
	Execution getDecisionInputExecution();

	/**
	 * Sets the value of the '{@link fUML.Semantics.Activities.IntermediateActivities.DecisionNodeActivation#getDecisionInputExecution <em>Decision Input Execution</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Decision Input Execution</em>' containment reference.
	 * @see #getDecisionInputExecution()
	 * @generated
	 */
	void setDecisionInputExecution(Execution value);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // If there is neither a decision input flow nor a decision input behavior,
	 *                   then return the set of values from the incoming tokens. 
	 *  // [In this
	 *                   case, the single incoming edge must be an object flow.]
	 *  // If there is a
	 *                   decision input flow, but no decision input behavior, then return a list of the
	 *                   decision input values equal in size to the number of incoming tokens.
	 *  //
	 *                   If there is both a decision input flow and a decision input behavior, then execute
	 *                   the decision input behavior once for each incoming token and return the set of
	 *                   resulting values.
	 *  // If the primary incoming edge is an object flow, then
	 *                   the value on each object token is passed to the decision input behavior, along
	 *                   with the decision input flow value, if any.
	 *  // If the primary incoming
	 *                   edge is a control flow, then the decision input behavior only receives the
	 *                   decision input flow, if any.
	 *  
	 *  
	 *  Value decisionInputValue
	 *                   = this.getDecisionInputFlowValue();
	 *  
	 *  ValueList decisionValues =
	 *                   new ValueList();
	 *  for (int i = 0; i < incomingTokens.size(); i++)
	 *                   {
	 *  Token incomingToken = incomingTokens.getValue(i);
	 *  Value value
	 *                   = this.executeDecisionInputBehavior(incomingToken.getValue(),
	 *                   decisionInputValue);
	 *  decisionValues.addValue(value);
	 *  }
	 *                   
	 *  // Debug.println("[getDecisionValues] " + decisionValues.size() + "
	 *                   decision value(s):");
	 *  for (int i = 0; i < decisionValues.size();
	 *                   i++) {
	 *  Value decisionValue = decisionValues.getValue(i);
	 *                   Debug.println("[getDecisionValues] decisionValues[" + i + "] = " +
	 *                   decisionValue);
	 *  }
	 *  
	 *  return decisionValues;
	 *                 
	 * <!-- end-model-doc -->
	 * @model ordered="false" incomingTokensMany="true" incomingTokensOrdered="false"
	 * @generated
	 */
	EList<Value> getDecisionValues(EList<Token> incomingTokens);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Create the decision input execution from the decision input
	 *                   behavior.
	 *  // If the behavior has input parameter(s), set the input
	 *                   parameter(s) of the execution to the given value(s).
	 *  // Execute the
	 *                   decision input execution and then remove it.
	 *  // Return the value of the
	 *                   output parameter of the execution.
	 *  // If there is no decision input
	 *                   behavior, the decision input value is returned, if one is given, otherwise the
	 *                   input value is used as the decision value.
	 *  
	 *                   Debug.println("[executeDecisionBehavior] inputValue = " + inputValue);
	 *                   
	 *  Behavior decisionInputBehavior =
	 *                   ((DecisionNode)(this.node)).decisionInput;
	 *  
	 *  Value
	 *                   decisionInputResult = null;
	 *  
	 *  if (decisionInputBehavior == null)
	 *                   {
	 *  
	 *  if (decisionInputValue != null) {
	 *                   decisionInputResult = decisionInputValue;
	 *  } else {
	 *                   decisionInputResult = inputValue;
	 *  }
	 *  
	 *  } else {
	 *                   
	 *  this.decisionInputExecution =
	 *                   this.getExecutionLocus().factory.createExecution(decisionInputBehavior,
	 *                   this.getExecutionContext());
	 *  
	 *  int i = 1;
	 *  int j =
	 *                   0;
	 *  while ((j == 0 | (j == 1 & decisionInputValue != null))
	 *                   & i <= decisionInputBehavior.ownedParameter.size()) {
	 *                   Parameter parameter = decisionInputBehavior.ownedParameter.getValue(i-1);
	 *                   if (parameter.direction.equals(ParameterDirectionKind.in) |
	 *                   parameter.direction.equals(ParameterDirectionKind.inout)) {
	 *                   ParameterValue inputParameterValue = new ParameterValue();
	 *                   inputParameterValue.parameter = parameter;
	 *  
	 *  j = j +1;
	 *                   if (j == 1 && inputValue != null) {
	 *                   inputParameterValue.values.addValue(inputValue);
	 *  } else {
	 *                   inputParameterValue.values.addValue(decisionInputValue);
	 *  }
	 *                   
	 *                   this.decisionInputExecution.setParameterValue(inputParameterValue);
	 *                   
	 *  }
	 *  i = i + 1;
	 *  }
	 *  
	 *                   this.decisionInputExecution.execute();
	 *  
	 *  ParameterValueList
	 *                   outputParameterValues =
	 *                   this.decisionInputExecution.getOutputParameterValues();
	 *                   decisionInputExecution.destroy();
	 *  
	 *  decisionInputResult =
	 *                   outputParameterValues.getValue(0).values.getValue(0);
	 *  
	 *                   }
	 *  
	 *  return decisionInputResult;
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" inputValueOrdered="false" decisionInputValueOrdered="false"
	 * @generated
	 */
	Value executeDecisionInputBehavior(Value inputValue, Value decisionInputValue);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Take the next token available on the decision input flow, if any, and
	 *                   return its value.
	 *  
	 *  ActivityEdgeInstance
	 *                   decisionInputFlowInstance = this.getDecisionInputFlowInstance();
	 *                   
	 *  Value value = null;
	 *  if (decisionInputFlowInstance != null)
	 *                   {
	 *  TokenList tokens =
	 *                   decisionInputFlowInstance.takeOfferedTokens();
	 *  if (tokens.size() >
	 *                   0) {
	 *  value = ((ObjectToken)(tokens.getValue(0))).value;
	 *                   }
	 *  }
	 *  
	 *  return value;
	 *  
	 * <!-- end-model-doc -->
	 * @model kind="operation" ordered="false"
	 * @generated
	 */
	Value getDecisionInputFlowValue();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Get the activity edge instance for the decision input flow, if
	 *                   any.
	 *  
	 *  ActivityEdge decisionInputFlow =
	 *                   ((DecisionNode)(this.node)).decisionInputFlow;
	 *  
	 *                   ActivityEdgeInstance edgeInstance = null;
	 *  if (decisionInputFlow != null)
	 *                   {
	 *  int i = 1;
	 *  while (edgeInstance == null & i
	 *                   <=this.incomingEdges.size()) {
	 *  ActivityEdgeInstance incomingEdge =
	 *                   this.incomingEdges.getValue(i-1);
	 *  if (incomingEdge.edge ==
	 *                   decisionInputFlow) {
	 *  edgeInstance = incomingEdge;
	 *  }
	 *  i =
	 *                   i + 1;
	 *  }
	 *  }
	 *  
	 *  return edgeInstance;
	 *                 
	 * <!-- end-model-doc -->
	 * @model kind="operation" ordered="false"
	 * @generated
	 */
	ActivityEdgeInstance getDecisionInputFlowInstance();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Test if the given value matches the guard. If there is no guard, return
	 *                   true.
	 *  
	 *  boolean guardResult = true;
	 *  if (guard != null)
	 *                   {
	 *  Value guardValue =
	 *                   this.getExecutionLocus().executor.evaluate(guard);
	 *  guardResult =
	 *                   guardValue.equals(value);
	 *  }
	 *  
	 *  return
	 *                   guardResult;
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" guardRequired="true" guardOrdered="false" valueRequired="true" valueOrdered="false"
	 * @generated
	 */
	boolean test(ValueSpecification guard, Value value);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model ordered="false" incomingTokensMany="true" incomingTokensOrdered="false"
	 * @generated
	 */
	EList<Token> removeJoinedControlTokens(EList<Token> incomingTokens);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @model required="true" ordered="false"
	 * @generated
	 */
	boolean hasObjectFlowInput();

} // DecisionNodeActivation
